<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus®">
  <meta name="Author" content="">
  <meta name="Keywords" content="">
  <meta name="Description" content="">
  <title>$listeners</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script>
  <style>

  </style>
 </head>
 <body>
    <div id="app">
      <base-input
        v-model="username"
        label="基础输入组件"
        @click.native="handleBaseInputClick"
        v-on:focus="handleBaseInputFocus"
        placeholder="请输入您的名字"
        class="username-input"/>
    </div>
    <script>
      // $listeners：包含了父组件中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用

      // 因为base-input的外层是一个label元素，所以默认情况下使用v-on:focus是无效的，所以需要配合$listeners使用，该属性可以把事件的监听指向组件中某个特定的元素
        Vue.component('base-input',{
          inheritAttrs: false,
          props: ['label','value'],
            template: `
              <label id="base-label">
                  {{label}}
                  <input v-bind:value="value" v-bind="$attrs" v-on="inputListeners"/>
              </label>
            `,
          computed: {
            inputListeners () {
                var _this = this
                return Object.assign({},
                    this.$listeners,
                    {
                      input: function () {
                        _this.$emit('input', event.target.value)
                      },
                      focus: function () {
                        _this.$emit('focus', event)
                      }
                      // focus: function (event) {
                      //   _this.$emit('focus', event)
                      // }
                    }
                )
            }
          },
          mounted: function(){
            console.log(`$attrs:`)
            console.log(this.$attrs)
            console.log(`$listeners:`)
            console.log(this.$listeners)
          }
        })
        var vm = new Vue({
          el: '#app',
          data: {
            username: ''
          },
          beforeUpdate: function () {
            console.log(this.username)
          },
          methods: {
            handleBaseInputFocus: function(ev){
              console.log('focus', ev)
            },
            handleBaseInputClick: function(ev){
              console.log('click', ev)
            }
          }
        })
    </script>
 </body>
</html>
